home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ctldlt.zip / CTLDTL.CPP < prev    next >
C/C++ Source or Header  |  1992-09-09  |  30KB  |  722 lines

  1. #include <owl.h>         // CTLCOL adds a Digital Display Custom
  2. #include <bwcc.h>        // Control that interfaces with the
  3. #include <custcntl.h>    // The Resource Workshop as well as
  4. #include <control.h>     // functions as a stand alone control.
  5. #include <static.h>      // It Parses ~ delimited data added to
  6. #include <edit.h>        // the title field to define the Digital Control's
  7. #include <bstatic.h>     // color.  Also adds the color Common dialog
  8. #include <commdlg.h>     // to allow a color selection from the
  9. #include "ctldtl.h"      // resource workshop.
  10.  
  11. PTModule CtlDtlModule;
  12. BOOL fInWorkshop;
  13. //==================================================================
  14. _CLASSDEF(TColorDialog)               // Class to encapsulate
  15. class TColorDialog : public TDialog   // the Windows 3.1
  16.   {                                   // Color Common Dialog
  17.   public:
  18.     DWORD dwCustClrs[16];             // Array for custom colors
  19.     TColorDialog(PTWindowsObject AParent, // Constructor
  20.          DWORD * dwNewColor, LPSTR lpName, PTModule AModule);
  21.     virtual BOOL Create();            // Create for non-modal Creation
  22.     virtual int Execute();            // Execute for modal Execution
  23.     virtual void CloseWindow(int ARetValue){}; // trap destruction
  24.   protected:
  25.     CHOOSECOLOR ccdlg;                // Color Common Dialog Structure
  26.     DWORD *dwColor;                   // Color Variable
  27.   };
  28. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
  29. TColorDialog::TColorDialog(PTWindowsObject AParent, DWORD * dwNewColor,
  30.                    LPSTR AName,PTModule AModule = NULL)
  31.          :TDialog(AParent,AName,AModule) // Constructor calls base
  32.   {
  33.   dwColor =  dwNewColor;        //equate color address to allow updating
  34.   int Count;                    //initialize the 16 custom colors to
  35.   for (Count = 0; Count <= 15; Count++) // Shades of blue
  36.     dwCustClrs[Count] = RGB(Count*(255/15),Count*(255/15),255);
  37.   ccdlg.lStructSize    = sizeof(CHOOSECOLOR);    // initialize ccdl struct
  38.   ccdlg.hwndOwner      = GetFocus();             // parent has the focus
  39.   ccdlg.hInstance      = NULL;                   // Not Used for default dlg
  40.   ccdlg.rgbResult      =  *dwNewColor;           // Color in
  41.   ccdlg.lpCustColors   = (LPDWORD)(dwCustClrs);  // array of blue colors
  42.   ccdlg.Flags          = CC_FULLOPEN|CC_RGBINIT; // full dialog with color in
  43.   ccdlg.lCustData      = 0L;                     // Use Default Data
  44.   ccdlg.lpfnHook       = (FARPROC)NULL;          // No Message trapping
  45.   ccdlg.lpTemplateName = (LPSTR)NULL;            // Use Default dialog
  46.   };
  47. BOOL TColorDialog::Create()                      // Called by MakeWindow
  48.   {
  49.   ccdlg.hwndOwner = NULL;                        // No parent for non-Model
  50.   ChooseColor(&ccdlg);                           // ccdlg function call
  51.   *dwColor = ccdlg.rgbResult;                    // Color out
  52.   return 1;                                      // Success
  53.   }
  54. int TColorDialog::Execute()                      // Called by CreateDialog
  55.   {
  56.   ChooseColor(&ccdlg);                           // ccdlg function call
  57.   *dwColor = ccdlg.rgbResult;                    // Color out
  58.   return 1;                                      // Success
  59.   }
  60. //=====================================================================
  61. //                   TColRect Custom Control
  62. char szClassName[]  = "Digital";   // class for new custom control
  63. //=====================================================================
  64. #pragma argsused  // TDigital methods prototype in header file
  65. TDigital::TDigital(PTWindowsObject AParent, int AnId,
  66.              int X, int Y, int W, int H,
  67.              LPSTR ATitle,
  68.              WORD  ATextLen,
  69.              PTModule AModule)
  70.             :TStatic (AParent, AnId, ATitle,X,Y,W,H,
  71.                   ATextLen,AModule){};
  72. //------------------------------------------------------------------------
  73. TDigital::TDigital(PTWindowsObject AParent, int ResourceId,
  74.                PTModule AModule)
  75.               :TStatic(AParent, ResourceId, 1, AModule){};
  76. //---------------------------------------------------------------------
  77. // PARSE function used by SetupWindow to pull 4 text fields out of one
  78. //       Title field delimited by the tilde character ~
  79. int TDigital::Parse(int StartChar)
  80.   {
  81.   int Count = 0;
  82.   while ((szTitle[StartChar] != '~')&(szTitle[StartChar] != NULL))
  83.     {
  84.     szBuffer[Count] = szTitle[StartChar];
  85.     StartChar++;
  86.     Count++;
  87.     };
  88.   szBuffer[Count] = NULL;
  89.   return StartChar;
  90.   }
  91. //---------------------------------------------------------------------
  92. void TDigital::SetupWindow()
  93.   {
  94.   int nCharCount = 0;
  95.   TStatic::SetupWindow();               // call base class
  96.   GetText(szTitle,254);                 // Get Title
  97.   nCharCount   = Parse(nCharCount);     // Parse out title
  98.   lstrcpy(szText,szBuffer);
  99.   nCharCount   = Parse(nCharCount+1);   // Parse out Red Value
  100.   int nRed     = atoi(szBuffer);
  101.   nCharCount   = Parse(nCharCount+1);   // Parse out Green
  102.   int nGreen   = atoi(szBuffer);
  103.   nCharCount   = Parse(nCharCount+1);   // Parse out Blue
  104.   int nBlue    = atoi(szBuffer);
  105.   DisplayColor = RGB(nRed,nGreen,nBlue); // Combine into a Color
  106.   if (fInWorkshop)                               // If in Workshop
  107.      InvalidateRect(Parent->HWindow,NULL,FALSE); // Update Parent
  108.   }
  109. //------------------------------------------------------------------------
  110. #pragma argsused                   // Public interface function
  111. void TDigital::WMColor(RTMessage Msg)// for TDigital Custom control
  112.   {                                // for prototypes in header file.
  113.   DisplayColor = Msg.LParam;       // Note the use of function pairs
  114.   InvalidateRect(HWindow,NULL,FALSE);
  115.   return;                          // to send a message from a member
  116.   }                                // function through windows to allow
  117. void TDigital::Color(COLORREF NewColor)// the dummy object to access data
  118.   {                                // in the display object.
  119.   SendMessage(HWindow,CR_COLOR,1,NewColor);
  120.   }
  121. //------------------------------------------------------------------------
  122. int TDigital::DisplayChar(char cDisplayChar, int nXOffset)
  123.   {                                // Outputs a single character
  124.   const int Top      = 1;          // Values for parts of control
  125.   const int Middle   = 2;
  126.   const int Bottom   = 4;
  127.   const int TopLeft  = 8;
  128.   const int TopRight = 16;
  129.   const int BotLeft  = 32;
  130.   const int BotRight = 64;
  131.   char      cDisplay = 0;          // Blank display
  132.   int       nP = Attr.H / 24;      // nP is a unit of measure
  133.   if (nP == 0) nP = 1;             // Always make it at least one pixel
  134.   int nMovePixel = nP * 17;        // Increment in 17 units to next character
  135.   switch (cDisplayChar)            // Figure the parts to display for
  136.     {                              // different digits
  137.     case '0':
  138.       cDisplay = Top | Bottom | TopLeft | TopRight | BotLeft | BotRight;
  139.       break;
  140.     case '1':
  141.       cDisplay = TopRight | BotRight;
  142.       break;
  143.     case '2':
  144.       cDisplay = Top | TopRight | Middle | BotLeft | Bottom;
  145.       break;
  146.     case '3':
  147.       cDisplay = Top | TopRight | Middle | BotRight | Bottom;
  148.       break;
  149.     case '4':
  150.       cDisplay = TopLeft | Middle | TopRight | BotRight;
  151.       break;
  152.     case '5':
  153.       cDisplay = Top | TopLeft | Middle | BotRight | Bottom;
  154.       break;
  155.     case '6':
  156.       cDisplay = TopLeft | BotLeft | Bottom | BotRight | Middle;
  157.       break;
  158.     case '7':
  159.       cDisplay = Top | TopRight | BotRight;
  160.       break;
  161.     case '8':
  162.       cDisplay = Top | Middle | Bottom | TopLeft | TopRight |
  163.               BotLeft | BotRight;
  164.       break;
  165.     case '9':
  166.       cDisplay = Top | Middle | Bottom | TopLeft | TopRight |
  167.               BotRight;
  168.       break;
  169.     case 'a':
  170.     case 'A':
  171.       cDisplay = Top | Middle | TopLeft | TopRight |
  172.               BotLeft | BotRight;
  173.       break;
  174.     case 'b':
  175.     case 'B':
  176.       cDisplay = TopLeft | BotLeft | Bottom | BotRight | Middle;
  177.       break;
  178.     case 'c':
  179.     case 'C':
  180.       cDisplay = Middle | Bottom | BotLeft;
  181.       break;
  182.     case 'd':
  183.     case 'D':
  184.       cDisplay = Middle | Bottom | BotLeft | BotRight | TopRight;
  185.       break;
  186.     case 'e':
  187.     case 'E':
  188.       cDisplay = Top | Middle | Bottom | TopLeft | BotLeft;
  189.       break;
  190.     case 'f':
  191.     case 'F':
  192.       cDisplay = Top | Middle | TopLeft | BotLeft;
  193.       break;
  194.     case 'P':
  195.       cDisplay = Top | Middle | TopLeft | TopRight | BotLeft;
  196.       break;
  197.     case '-':
  198.       cDisplay = Middle;
  199.       break;
  200.     case '(':
  201.       cDisplay = TopLeft | BotLeft;
  202.       nXOffset += 4 * nP;
  203.       break;
  204.     case ')':
  205.       cDisplay = TopRight | BotRight;
  206.       nXOffset -= 4 * nP;
  207.       break;
  208.     default:
  209.       cDisplay = 0;
  210.       break;
  211.     }
  212.   HPEN   hPen,   hOldPen;                       // Pen Variables
  213.   HBRUSH hBrush, hOldBrush;                     // Brush Variables
  214.   HDC hDC = GetDC(HWindow);                     // grab the Device Context
  215.   hPen      = CreatePen(PS_SOLID,1,DisplayColor); // Colored pen
  216.   hOldPen   = (HPEN)SelectObject(hDC,hPen);     // use  pen
  217.   hBrush    = (HBRUSH)CreateSolidBrush(DisplayColor); // Colored brush
  218.   hOldBrush = (HBRUSH)SelectObject(hDC,hBrush); // use brush
  219.   POINT apShape[6];                             // 6 parts for shapes
  220.   if (cDisplay & Top)                           // display the top
  221.     {                                           // polygon
  222.     apShape[0].x = nP * 2 * 2 + nXOffset;
  223.     apShape[0].y = nP * 2;
  224.     apShape[1].x = nP * 17+ nXOffset;
  225.     apShape[1].y = nP * 2;
  226.     apShape[2].x = nP * 13+ nXOffset;
  227.     apShape[2].y = nP * 5;
  228.     apShape[3].x = nP * 4 * 2+ nXOffset;
  229.     apShape[3].y = nP * 5;
  230.     Polygon(hDC, apShape, 4);
  231.     }
  232.   if (cDisplay & Bottom)                        // Display the bottom
  233.     {                                           // Polygon
  234.     apShape[0].x = nP * 2 * 2+ nXOffset;
  235.     apShape[0].y = nP * 22;
  236.     apShape[1].x = nP * 17+ nXOffset;
  237.     apShape[1].y = nP * 22;
  238.     apShape[2].x = nP * 13+ nXOffset;
  239.     apShape[2].y = nP * 19;
  240.     apShape[3].x = nP * 8+ nXOffset;
  241.     apShape[3].y = nP * 19;
  242.     Polygon(hDC, apShape, 4);
  243.     }
  244.   if (cDisplay & Middle)
  245.     {
  246.     apShape[0].x = nP * 6+ nXOffset;              // Middle
  247.     apShape[0].y = nP * 12;
  248.     apShape[1].x = nP * 8+ nXOffset;
  249.     apShape[1].y = nP * 11;
  250.     apShape[2].x = nP * 13+ nXOffset;
  251.     apShape[2].y = nP * 11;
  252.     apShape[3].x = nP * 15+ nXOffset;
  253.     apShape[3].y = nP * 12;
  254.     apShape[4].x = nP * 13+ nXOffset;
  255.     apShape[4].y = nP * 13;
  256.     apShape[5].x = nP * 4 * 2+ nXOffset;
  257.     apShape[5].y = nP * 13;
  258.     Polygon(hDC, apShape, 6);
  259.     }
  260.   if (cDisplay & TopLeft)
  261.     {
  262.     apShape[0].x = nP * 2 * 2+ nXOffset;              // Top Left
  263.     apShape[0].y = nP * 4;
  264.     apShape[1].x = nP * 2 * 2+ nXOffset;
  265.     apShape[1].y = nP * 12;
  266.     apShape[2].x = nP * 7+ nXOffset;
  267.     apShape[2].y = nP * 10;
  268.     apShape[3].x = nP * 7+ nXOffset;
  269.     apShape[3].y = nP * 6;
  270.     Polygon(hDC, apShape, 4);
  271.     }
  272.   if (cDisplay & BotLeft)
  273.     {
  274.     apShape[0].x = nP * 2 * 2 + nXOffset;              // Bottom Left
  275.     apShape[0].y = nP * 12;
  276.     apShape[1].x = nP * 2 * 2+ nXOffset;
  277.     apShape[1].y = nP * 20;
  278.     apShape[2].x = nP * 7+ nXOffset;
  279.     apShape[2].y = nP * 18;
  280.     apShape[3].x = nP * 7+ nXOffset;
  281.     apShape[3].y = nP * 14;
  282.     Polygon(hDC, apShape, 4);
  283.     }
  284.   if (cDisplay & TopRight)
  285.     {
  286.     apShape[0].x = nP * 17+ nXOffset;              // Top Right
  287.     apShape[0].y = nP * 4;
  288.     apShape[1].x = nP * 17+ nXOffset;
  289.     apShape[1].y = nP * 12;
  290.     apShape[2].x = nP * 14+ nXOffset;
  291.     apShape[2].y = nP * 10;
  292.     apShape[3].x = nP * 14+ nXOffset;
  293.     apShape[3].y = nP * 6;
  294.     Polygon(hDC, apShape, 4);
  295.     }
  296.   if (cDisplay & BotRight)
  297.     {
  298.     apShape[0].x = nP * 17+ nXOffset;              // Bottom right
  299.     apShape[0].y = nP * 12;
  300.     apShape[1].x = nP * 17+ nXOffset;
  301.     apShape[1].y = nP * 20;
  302.     apShape[2].x = nP * 14+ nXOffset;
  303.     apShape[2].y = nP * 18;
  304.     apShape[3].x = nP * 14+ nXOffset;
  305.     apShape[3].y = nP * 14;
  306.     Polygon(hDC, apShape, 4);
  307.     }
  308.   switch (cDisplayChar)                    // Special characters
  309.     {
  310.     case ':':
  311.       nMovePixel = nP * 5;
  312.       Ellipse(hDC,nP * 3 + nXOffset, nP * 6,nP * 7 + nXOffset, nP * 10);
  313.       Ellipse(hDC,nP * 3 + nXOffset, nP * 15,nP * 7 + nXOffset, nP * 19);
  314.       break;
  315.     case '.':
  316.       nMovePixel = nP * 5;
  317.       Ellipse(hDC,nP * 3 + nXOffset, nP * 19,nP * 7 + nXOffset, nP * 23);
  318.       break;
  319.     case ',':
  320.       nMovePixel = nP * 5;
  321.       Ellipse(hDC,nP * 3 + nXOffset, nP * 19,nP * 7 + nXOffset, nP * 23);
  322.       apShape[0].x = nP * 5 + nXOffset;
  323.       apShape[0].y = nP * 21;
  324.       apShape[1].x = nP * 6 + nXOffset;
  325.       apShape[1].y = nP * 22;
  326.       apShape[2].x = nP * 3 + nXOffset;
  327.       apShape[2].y = nP * 25;
  328.       Polygon(hDC, apShape, 3);
  329.       break;
  330.     case '(':
  331.       nMovePixel = nP * 12;
  332.       apShape[0].x = nP * 2 * 2 + nXOffset;              // Top
  333.       apShape[0].y = nP * 2;
  334.       apShape[1].x = nP * 12 + nXOffset;
  335.       apShape[1].y = nP * 2;
  336.       apShape[2].x = nP * 8 + nXOffset;
  337.       apShape[2].y = nP * 5;
  338.       apShape[3].x = nP * 4 * 2+ nXOffset;
  339.       apShape[3].y = nP * 5;
  340.       Polygon(hDC, apShape, 4);
  341.       apShape[0].x = nP * 2 * 2+ nXOffset;              // Bottom
  342.       apShape[0].y = nP * 22;
  343.       apShape[1].x = nP * 12 + nXOffset;
  344.       apShape[1].y = nP * 22;
  345.       apShape[2].x = nP * 8  + nXOffset;
  346.       apShape[2].y = nP * 19;
  347.       apShape[3].x = nP * 8+ nXOffset;
  348.       apShape[3].y = nP * 19;
  349.       Polygon(hDC, apShape, 4);
  350.       break;
  351.     case ')':
  352.       nMovePixel = nP * 16;
  353.       nXOffset += 4 * nP;
  354.       apShape[0].x = nP * 2 * 2 + nXOffset;              // Top
  355.       apShape[0].y = nP * 2;
  356.       apShape[1].x = nP * 12 + nXOffset;
  357.       apShape[1].y = nP * 2;
  358.       apShape[2].x = nP * 8 + nXOffset;
  359.       apShape[2].y = nP * 5;
  360.       apShape[3].x = nP * 4 * 2+ nXOffset;
  361.       apShape[3].y = nP * 5;
  362.       Polygon(hDC, apShape, 4);
  363.       apShape[0].x = nP * 2 * 2+ nXOffset;              // Bottom
  364.       apShape[0].y = nP * 22;
  365.       apShape[1].x = nP * 12 + nXOffset;
  366.       apShape[1].y = nP * 22;
  367.       apShape[2].x = nP * 8  + nXOffset;
  368.       apShape[2].y = nP * 19;
  369.       apShape[3].x = nP * 8+ nXOffset;
  370.       apShape[3].y = nP * 19;
  371.       Polygon(hDC, apShape, 4);
  372.       break;
  373.     case '$':
  374.       apShape[0].x = nP * 2 * 2 + nXOffset;    // Top
  375.       apShape[0].y = nP * 6;
  376.       apShape[1].x = nP * 17+ nXOffset;
  377.       apShape[1].y = nP * 6;
  378.       apShape[2].x = nP * 13+ nXOffset;
  379.       apShape[2].y = nP * 9;
  380.       apShape[3].x = nP * 4 * 2+ nXOffset;
  381.       apShape[3].y = nP * 9;
  382.       Polygon(hDC, apShape, 4);
  383.       apShape[0].x = nP * 2 * 2+ nXOffset;              // Bottom
  384.       apShape[0].y = nP * 18;
  385.       apShape[1].x = nP * 17+ nXOffset;
  386.       apShape[1].y = nP * 18;
  387.       apShape[2].x = nP * 13+ nXOffset;
  388.       apShape[2].y = nP * 15;
  389.       apShape[3].x = nP * 8+ nXOffset;
  390.       apShape[3].y = nP * 15;
  391.       Polygon(hDC, apShape, 4);
  392.       apShape[0].x = nP * 6+ nXOffset;              // Middle
  393.       apShape[0].y = nP * 12;
  394.       apShape[1].x = nP * 8+ nXOffset;
  395.       apShape[1].y = nP * 11;
  396.       apShape[2].x = nP * 13+ nXOffset;
  397.       apShape[2].y = nP * 11;
  398.       apShape[3].x = nP * 15+ nXOffset;
  399.       apShape[3].y = nP * 12;
  400.       apShape[4].x = nP * 13+ nXOffset;
  401.       apShape[4].y = nP * 13;
  402.       apShape[5].x = nP * 4 * 2+ nXOffset;
  403.       apShape[5].y = nP * 13;
  404.       Polygon(hDC, apShape, 6);
  405.       apShape[0].x = nP * 2 * 2+ nXOffset;              // Top Left
  406.       apShape[0].y = nP * 8;
  407.       apShape[1].x = nP * 2 * 2+ nXOffset;
  408.       apShape[1].y = nP * 12;
  409.       apShape[2].x = nP * 7+ nXOffset;
  410.       apShape[2].y = nP * 10;
  411.       apShape[3].x = nP * 7+ nXOffset;
  412.       apShape[3].y = nP * 10;
  413.       Polygon(hDC, apShape, 4);
  414.       apShape[0].x = nP * 17+ nXOffset;              // Bottom right
  415.       apShape[0].y = nP * 12;
  416.       apShape[1].x = nP * 17+ nXOffset;
  417.       apShape[1].y = nP * 16;
  418.       apShape[2].x = nP * 14+ nXOffset;
  419.       apShape[2].y = nP * 14;
  420.       apShape[3].x = nP * 14+ nXOffset;
  421.       apShape[3].y = nP * 14;
  422.       Polygon(hDC, apShape, 4);
  423.       Rectangle(hDC,nP * 9 + nXOffset, nP * 1,nP * 13 + nXOffset, nP * 5);
  424.       Rectangle(hDC,nP * 9 + nXOffset, nP * 19,nP * 13 + nXOffset, nP * 23);
  425.       break;
  426.     default:
  427.       break;
  428.     }
  429.   SelectObject(hDC,hOldBrush);                  // restore old brush
  430.   DeleteObject(hBrush);                         // destroy new brush
  431.   SelectObject(hDC,hOldPen);                    // restore pen
  432.   DeleteObject(hPen);                           // destroy new pen
  433.   ReleaseDC(HWindow,hDC);                       // release the Device Context
  434.   return (nXOffset + nMovePixel);
  435.   }
  436. //------------------------------------------------------------------------
  437. void TDigital::WMPaint(RTMessage Msg)
  438.   {
  439.   for (int nDisplayPos = 0, Count = 0;
  440.        Count < lstrlen(szText);
  441.        nDisplayPos = DisplayChar(szText[Count++],nDisplayPos));
  442.   ValidateRect(HWindow,NULL);                   // Mark the window as painted
  443.   Msg.Result = 0;                               // Success
  444.   }
  445. //------------------------------------------------------------------------
  446. LPSTR TDigital::GetClassName()
  447.   {
  448.   return szClassName;
  449.   }
  450. //------------------------------------------------------------------------
  451. LONG FAR PASCAL _export DigitalWndProc(HWND HWindow,  // Main process
  452.                     WORD wMsg,    // registered
  453.                     WORD wParam,  // in following
  454.                     LONG lParam)  // function
  455.   {
  456.   if (wMsg == WM_CREATE)    // if Called by non-OWL application (RW)
  457.     {
  458.     PTDigital PDigital =  // Create an instance
  459.       new TDigital(CtlDtlModule->GetParentObject(GetParent(HWindow)),
  460.              GetWindowWord(HWindow, GWW_ID),
  461.              CtlDtlModule);
  462.     CtlDtlModule->MakeWindow(PDigital); // hook module to a window
  463.     }
  464.   return DefWindowProc(HWindow, wMsg, wParam, lParam); // allow Windows
  465.   }          // to handle messages prior to OWL hooking into the window
  466. //------------------------------------------------------------------------
  467. BOOL RegisterDigitalClass(HINSTANCE hInstance)  // Called by Libmain to
  468. {                                           // register the Window Class
  469.   WNDCLASS  wc;
  470.   wc.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
  471.   wc.lpfnWndProc   = (WNDPROC)DigitalWndProc;  // Registers Proc used by Class
  472.   wc.cbClsExtra    = 0;
  473.   wc.cbWndExtra    = 0;
  474.   wc.hInstance     = hInstance;
  475.   wc.hIcon         = NULL;
  476.   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  477.   wc.hbrBackground = (HBRUSH)(NULL_BRUSH);    //(Clear Background);
  478.   wc.lpszMenuName  = NULL;
  479.   wc.lpszClassName   = szClassName;
  480.   return RegisterClass(&wc);
  481.   }
  482. //------------------------------------------------------------------------
  483. _CLASSDEF(TDigitalDlg)              // Workshop Functions
  484. class TDigitalDlg : public TDialog  // Dialog Class used by Workshop when
  485.   {                               // The Control is double clicked
  486.   protected:
  487.     LPFNSTRTOID    StrToId;       // Pointers to items in workshop
  488.     LPFNIDTOSTR    IdToStr;       // That are used in dialog
  489.     LPCTLSTYLE     Style;
  490.     PTEdit         pTitle;        // Control pointers
  491.     PTEdit         pIdText;
  492.     PTBStatic      pIdNum;
  493.     PTEdit         pRed;
  494.     PTEdit         pGreen;
  495.     PTEdit         pBlue;
  496.     char           szBuffer[80];  // Line Buffer
  497.     WORD           wType;         // Control Type
  498.     public:
  499.     TDigitalDlg(PTWindowsObject AParent, LPSTR AName,
  500.           LPFNSTRTOID PStrToId, LPFNIDTOSTR PIdToStr,
  501.           LPCTLSTYLE  PStyle, PTModule AModule = NULL);
  502.     int Parse(int StartChar);
  503.     void SetupWindow();
  504.     virtual void PaletteButton(RTMessage Msg) // button handler
  505.       = [ID_FIRST + IDB_PALETTE];
  506.     void Ok(RTMessage Msg) = [ID_FIRST + IDOK];
  507.   };
  508. //------------------------------------------------------------------------
  509. TDigitalDlg::TDigitalDlg(PTWindowsObject AParent, LPSTR AName,
  510.              LPFNSTRTOID PStrToId, LPFNIDTOSTR PIdToStr,
  511.              LPCTLSTYLE  PStyle, PTModule AModule)
  512.       :TDialog(AParent, AName, AModule),    // Base Class
  513.        StrToId(PStrToId),                   // Three functions
  514.        IdToStr(PIdToStr),                   // in Worshop that
  515.        Style(PStyle)                        // are used
  516.   {
  517.   pTitle      = new TEdit(this,      IDD_TITLE, CTLTITLE, CtlDtlModule);
  518.   pIdText     = new TEdit(this,      IDD_IDTEXT, 255, CtlDtlModule);
  519.   pIdNum      = new TBStatic(this,   IDD_IDNUM,   18, CtlDtlModule);
  520.   pRed        = new TEdit(this,      IDD_IDRED,    4, CtlDtlModule);
  521.   pGreen      = new TEdit(this,      IDD_IDGREEN,  4, CtlDtlModule);
  522.   pBlue       = new TEdit(this,      IDD_IDBLUE,   4, CtlDtlModule);
  523.   }
  524. //---------------------------------------------------------------------
  525. // PARSE function used by SetupWindow to pull 4 text fields out of one
  526. //       Title field delimited by the tilde character ~
  527. int TDigitalDlg::Parse(int StartChar)
  528.   {
  529.   int Count = 0;
  530.   while ((Style->szTitle[StartChar] != '~')&(Style->szTitle[StartChar] != NULL))
  531.     {
  532.     szBuffer[Count] = Style->szTitle[StartChar];
  533.     StartChar++;
  534.     Count++;
  535.     };
  536.   szBuffer[Count] = NULL;
  537.   return StartChar;
  538.   }
  539. //---------------------------------------------------------------------
  540. void TDigitalDlg::SetupWindow()
  541.   {
  542.   int   nCharCount = 0;
  543.   char  buf[256];
  544.   TDialog::SetupWindow();             // call base class
  545.   nCharCount = Parse(nCharCount);     // Parse 4 fields out of title
  546.   pTitle->SetText(szBuffer);          // and initialize controls
  547.   nCharCount = Parse(nCharCount+1);
  548.   pRed->SetText(szBuffer);
  549.   nCharCount = Parse(nCharCount+1);
  550.   pGreen->SetText(szBuffer);
  551.   nCharCount = Parse(nCharCount+1);
  552.   pBlue->SetText(szBuffer);
  553.  
  554.   IdToStr(Style->wId, buf, 255);      // Use Workshop to get ID
  555.   pIdText->SetText(buf);              // String and store it
  556.   itoa(Style->wId, buf, 10);          // Translate it to a Number
  557.   pIdNum->SetText(buf);               // and Store Number
  558.   wType = 0xFFFFL & LOWORD(Style->dwStyle); // Save control Type
  559.   }
  560. //----------------------------------------------------------------------
  561. void TDigitalDlg:: PaletteButton(RTMessage)     // button activates
  562.   {
  563.   char szColorBuf[6];
  564.   pRed->GetText(szColorBuf, 4);          // Get Red Mix
  565.   int nRed  = atoi(szColorBuf);
  566.   pGreen->GetText(szColorBuf, 4);        // Get Green Mix
  567.   int nGreen  = atoi(szColorBuf);
  568.   pBlue->GetText(szColorBuf, 4);         // Get Blue Mix
  569.   int nBlue  = atoi(szColorBuf);
  570.   DWORD dwNewColor = RGB(nRed,nGreen,nBlue); // Combine into a Color
  571.  
  572.   CtlDtlModule->ExecDialog(new TColorDialog(
  573.                 CtlDtlModule->GetParentObject(HWindow),
  574.                 &dwNewColor,"Color_Dialog",CtlDtlModule));
  575.  
  576.   wsprintf (szColorBuf,"%d",GetRValue(dwNewColor));
  577.   pRed->SetText(szColorBuf);
  578.   wsprintf (szColorBuf,"%d",GetGValue(dwNewColor));
  579.   pGreen->SetText(szColorBuf);
  580.   wsprintf (szColorBuf,"%d",GetBValue(dwNewColor));
  581.   pBlue->SetText(szColorBuf);
  582.   }
  583. //----------------------------------------------------------------------
  584. #pragma argsused
  585. void TDigitalDlg::Ok(RTMessage Msg)      // OK Button pressed
  586.   {
  587.   char  szBuf[256];                   // Buffer for ID string
  588.   LONG  lRetId;                       // Id by Value
  589.   pIdText->GetText(szBuf, 255);       // Get the Text for the Control ID
  590.   lRetId = StrToId(szBuf);            // Convert the define to its number
  591.   if (LOWORD(lRetId) == 0)            // if the number is blank
  592.     {
  593.     pIdText->SetSelection(0, 32767);  // Select a default Number
  594.     SetFocus(pIdText->HWindow);       // Set the focus to the Control
  595.     Msg.Result = (LONG)TRUE;          // return(TRUE);
  596.     return;                           // Return to Dialog for more input
  597.     }
  598.   Style->wId = HIWORD(lRetId);             // not blank - so set the wId
  599.   pTitle->GetText(szBuf, CTLTITLE);        // Get the Title from control
  600.   lstrcat(szBuf,"~");                      // Add delimiter
  601.   pRed->GetText(szBuffer, 4);              // Get Red Mix
  602.   lstrcat(szBuf,szBuffer);                 // Append to string
  603.   lstrcat(szBuf,"~");                      // Add delimiter
  604.   pGreen->GetText(szBuffer, 4);            // Get Green Mix
  605.   lstrcat(szBuf,szBuffer);                 // Append to string
  606.   lstrcat(szBuf,"~");                      // Add delimiter
  607.   pBlue->GetText(szBuffer, 4);             // Get Blue Mix
  608.   lstrcat(szBuf,szBuffer);                 // Append to string
  609.   lstrcpy(Style->szTitle, szBuf);          // Copy to structure
  610.   Style->dwStyle = WS_CHILD | WS_VISIBLE | wType ;
  611.   CloseWindow(TRUE);                       // Close Window and update
  612.   }                                        // Workshop Structure
  613. //-------------------------------------------------------------------
  614. #pragma argsused                  // displays dialog box in RW to allow
  615. BOOL FAR PASCAL _export DigitalStyle(HWND HWindow,         // user to
  616.                       HANDLE hCtlStyle,     // change
  617.                       LPFNSTRTOID StrToId,  // control
  618.                       LPFNIDTOSTR IdToStr)  // attributes
  619. {
  620.   PTDigitalDlg    PDlg;
  621.   LPCTLSTYLE    PStyle  = (LPCTLSTYLE) GlobalLock(hCtlStyle);
  622.   BOOL          fRetval = FALSE;
  623.   if (PStyle)                // If Style locked OK
  624.     {                        // then Display dialog box
  625.       PDlg = new TDigitalDlg(CtlDtlModule->GetParentObject(HWindow),
  626.              (LPSTR)MAKEINTRESOURCE(CTLDTLDLG),
  627.              (LPFNSTRTOID)StrToId,
  628.              (LPFNIDTOSTR)IdToStr,
  629.              (LPCTLSTYLE)PStyle,
  630.              CtlDtlModule);
  631.     fRetval = (IDOK == CtlDtlModule->ExecDialog(PDlg) );
  632.     GlobalUnlock(hCtlStyle);  // cleanup
  633.   }
  634.   return fRetval;             // return Flag to RW
  635. }
  636. //-------------------------------------------------------------------
  637. #pragma argsused                                   // Called by RW to
  638. WORD FAR PASCAL _export DigitalFlags(DWORD dwStyle, // translate style
  639.                       LPSTR szBuf,   // bits to text
  640.                       WORD wbufLen)  // for clarity
  641.   {
  642.   wsprintf(szBuf,(LPSTR)"0");  // No Style bits so use
  643.   return lstrlen(szBuf);       // the Character for zero
  644.   }
  645. //-------------------------------------------------------------------
  646. HANDLE FAR PASCAL _export DigitalInfo(void)  // Info function for RW
  647. {                                             // Default Control Settings
  648.   HANDLE hInfo = GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT, sizeof(RWCTLINFO));
  649.   if ( hInfo )
  650.     {
  651.     LPRWCTLINFO Info = (LPRWCTLINFO) GlobalLock(hInfo);
  652.     Info->wVersion = 0x0100;             // Version 1.00 of DLL
  653.     Info->wCtlTypes = 1;                 // Number of  controls in Function
  654.     lstrcpy(Info->szClass, szClassName);  // for instance of control
  655.     lstrcpy(Info->szTitle, "P12:55:00~255~0~0"); // Caption
  656.                      // fill control structure
  657.     Info->Type[0].wType   = 0;           // Microsoft requires 0
  658.     Info->Type[0].wWidth  = 0x8000 | 140; // default width
  659.     Info->Type[0].wHeight = 0x8000 | 28; // default height
  660.     lstrcpy(Info->Type[0].szDescr, "Digital");//Must be different
  661.     Info->Type[0].dwStyle = WS_VISIBLE | WS_CHILD ;
  662.     Info->Type[0].hToolBit =            // Bitmap for Workshop palett
  663.       LoadBitmap(CtlDtlModule->hInstance, "CTLDTLBMP");
  664.     Info->Type[0].hDropCurs =           // Cursor for Workshop
  665.       LoadCursor(CtlDtlModule->hInstance, "CTLDTLCUR");
  666.     GlobalUnlock(hInfo);                // Unlock memory
  667.     }
  668.   return hInfo;                         // let RW have the memory
  669.   }
  670. //========================================================================
  671. #pragma argsused            // Used by RW to define controls
  672. extern "C" HANDLE FAR PASCAL _export ListClasses(LPSTR szAppName,
  673.                       WORD wVersion,
  674.                       LPFNLOADRES fnLoad,
  675.                       LPFNEDITRES fnEdit)
  676. {
  677.     HANDLE hClasses = GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT,
  678.     sizeof(int) + sizeof(RWCTLCLASS));
  679.     if ( hClasses )
  680.     {
  681.     LPCTLCLASSLIST Classes = (LPCTLCLASSLIST) GlobalLock(hClasses);
  682.     Classes->nClasses = 1;
  683.     Classes->Classes[0].fnRWInfo  = DigitalInfo;  // Three functions
  684.     Classes->Classes[0].fnRWStyle = DigitalStyle; // Workshop Calls
  685.     Classes->Classes[0].fnFlags   = (LPFNFLAGS)DigitalFlags;
  686.     lstrcpy(Classes->Classes[0].szClass, szClassName);
  687.     GlobalUnlock(hClasses);
  688.     }
  689.     fInWorkshop = TRUE;
  690.     return hClasses;
  691. }
  692. //------------------------------------------------------------------------
  693. WORD FAR PASCAL _export CTLDTLGetVersion(void)
  694.   {
  695.   return 0x0100;
  696.   }
  697. //------------------------------------------------------------------------
  698. int FAR PASCAL _export CTLDTLAbout(void)
  699.   {
  700.   return MessageBox(GetFocus(),"By Bob Bourbonnais",
  701.             "Custom Digital Control",MB_OK);
  702.   }
  703. //------------------------------------------------------------------------
  704. #pragma argsused
  705. extern "C" int FAR PASCAL _export WEP(int nParameter)
  706. {
  707.   return (1);
  708. }
  709. //------------------------------------------------------------------------
  710. #pragma argsused
  711. extern "C" int FAR PASCAL LibMain(HINSTANCE hInstance, WORD wDataSeg,
  712.                  WORD cbHeapSize, LPSTR lpCmdLine)
  713. {
  714.   if (cbHeapSize > 0)
  715.     UnlockData(0);
  716.   CtlDtlModule = new TModule("DigitalMod", hInstance, lpCmdLine);
  717.   RegisterDigitalClass(CtlDtlModule->hInstance);
  718.   fInWorkshop = FALSE;
  719.   return (1);
  720. }
  721. //=======================================================================//
  722.